/**
 * @file BusProtocol.c
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2023-08-17
 * 
 * @copyright Copyright (c) 2023
 * 
 */

#include "BusProtocol.h"
#include "delay.h"
#include "Start.h"
 
#define	ERR_DATA	0XFFFFFFFF

PRO_StatusTypeDef	ReadEndSingle(unsigned	short addr,unsigned	int *data);
 unsigned	short	GetSerialCode(void);



/**
 * @brief slave card control CMD
 * 
 */
enum	CMDCODE{
		SLAVE_CMD_STOP	=	0,
		SLAVE_CMD_REG_RD,
		SLAVE_CMD_REG_WT,
		SLAVE_CMD_SCAN,
		SLAVE_CMD_READ,
		SLAVE_CMD_DISCHARGE,
		SLAVE_CMD_RDENDPIN
};

enum	TIMEOUT{

		DISCHARGE_TIMEOUT	=	1000,
		GETDATA_TIMEOUT		=	1000,
		READSINGLE_TIMEOUT	=	1000
};

 

/**
 * @brief 
 * 
 */
DataStatBusUn  		gcurdatabus; /*保存当前数据和状态总线数据*/
CmdCtlUn 			gcurcmd; 	/*保存当前要发送的命令*/


static	unsigned	int	gSerialCode	=	0x00;
 unsigned	short	GetSerialCode(void){
					return	gSerialCode	++;
 };

 
 
/**
 * @brief 设计一个获取 放电结果的函数
 * 
 * @return PRO_StatusTypeDef 
 */
PRO_StatusTypeDef	SlaveCardDisCharge(void){
	unsigned	int			timeout;
	
	/*填充要发送的命令，只需要命令字和串码即可*/
	gcurcmd.CmdCtl.CtlCmd		=	SLAVE_CMD_DISCHARGE;
	gcurcmd.CmdCtl.SerialCode	=	GetSerialCode(); 
	
	write_Ctrl_Bus(gcurcmd.AllBits ); 	
	timeout = DISCHARGE_TIMEOUT;
	do{
		//delay_us(1);
		gcurdatabus.AllBits	=	Read_StatusData_Bus(); 
		timeout--; 
	}while(((gcurdatabus.CmdAck.CtlCmd!=gcurcmd.CmdReg.CtlCmd)||	\
			(gcurdatabus.CmdAck.SerialCode!=gcurcmd.CmdReg.SerialCode))&&	\
			(timeout!=0));
 
	if(timeout == 0)
	{ 
		return	PRO_TIMEOUT; 
	}else
	{ 
		//*data = gcurdatabus.RxData.Data1 |(gcurdatabus.RxData.Data2<<16);
		return	PRO_OK;   
	}  
}
/**
 * @brief Get the End Data object
 * 
 * @param data   返回的数据在这里
 * @return unsigned short 	数据的个数
 */
unsigned short	GetEndData(unsigned short *data){ 
	u32	timeout;  

	gcurcmd.CmdCtl.CtlCmd		=	SLAVE_CMD_SCAN;
	gcurcmd.CmdCtl.SerialCode	=	GetSerialCode();  
	
	write_Ctrl_Bus(gcurcmd.AllBits ); 	
	timeout = GETDATA_TIMEOUT;
	do{
		delay_us(1);
		gcurdatabus.AllBits	=	Read_StatusData_Bus(); 
		timeout--;
		
	}while(((gcurdatabus.CmdAck.CtlCmd!=gcurcmd.CmdReg.CtlCmd)||	\
			(gcurdatabus.CmdAck.SerialCode!=gcurcmd.CmdReg.SerialCode))&&	\
			(timeout!=0));
 
	if(timeout == 0)
	{ 
		return	0; 
	}else
	{  
		data[0] = gcurdatabus.DataAck.value1;
		data[1] = gcurdatabus.DataAck.value2;	
		return	gcurdatabus.DataAck.ret;  
	} 
}

/**
 * @brief 
 * 
 * @param addr :
 * @param data 
 * @param len  每次读取的个数
 * @return PRO_StatusTypeDef 
 */
PRO_StatusTypeDef	ReadEnd(unsigned	short addr,\
							unsigned	short *data,\
							unsigned	short	len){
	u32		rxdata;	
 
	if(PRO_OK==ReadEndSingle(addr,&rxdata))
	{
		
		data[0] = 		rxdata&0xffff; 
		data[1] =		(rxdata&0xffff0000)>>16; 	
	}else
	{
		return	PRO_ERROR; 
	}	 
	return	PRO_OK; 	
}

/**
 * @brief 读取slave card的数据，可以选择读取1或2个数据 每个数据长度12bit
 * 
 * @param addr 
 * @param data 
 * @return PRO_StatusTypeDef 
 */
PRO_StatusTypeDef	ReadEndSingle(unsigned	short addr,unsigned	int *data){
	u32	timeout;
	u16		data1,data2;
	
	gcurcmd.CmdReadEnd.CtlCmd		=	SLAVE_CMD_READ;
	gcurcmd.CmdReadEnd.SerialCode	=	GetSerialCode();  
	gcurcmd.CmdReadEnd.CtlEndIndex	=	addr; 
	
	write_Ctrl_Bus(gcurcmd.AllBits ); 	
	timeout = READSINGLE_TIMEOUT;
	do{
		delay_us(1);
		gcurdatabus.AllBits	=	Read_StatusData_Bus(); 
		timeout--;
		
	}while(((gcurdatabus.CmdAck.CtlCmd!=gcurcmd.CmdReg.CtlCmd)||	\
			(gcurdatabus.CmdAck.SerialCode!=gcurcmd.CmdReg.SerialCode))&&	\
			(timeout!=0));
 
	if(timeout == 0)
	{
		*data = ERR_DATA;
		return	PRO_ERROR; 
	}else
	{
		*data = 0xffff | ((unsigned int)0xeeee<<16);
		data1	=	gcurdatabus.DataAck.value1;
		data2	=	gcurdatabus.DataAck.value2;
		*data	=	data1|(data2<<16); 
		return	PRO_OK;   
	} 
}



